﻿/*
 
Celerity: Sensory Overload
Copright 2012 by Adam Hill, David Gannon, Thomas Tamblyn & Patrick Ytting
Contact: adam.hill@outlook.com
Website: adamhill.org
Licence: MS-Pl Licence
  
 */

namespace Celerity.Logic
{
    using Celerity.Audio;
    using Celerity.Data;
    using Celerity.Input;
    using Microsoft.Xna.Framework;
    using System;

    public class GameLogic
    {
        #region Instance Variables
        double timeSinceCrash = 0.0;
        AudioModule audio;
        InputModule input;
        #endregion /Instance Variables

        #region Properties
        public float ChaosFactor = 0.5f;
        public bool DoFireSmartBomb = false;
        public bool DisplayShip { get { return GlobalGameStates.GameState != GameState.GameOver; } }
        #endregion /Properties

        #region Constructor
        public GameLogic(AudioModule audio, InputModule input)
        {
            this.audio = audio;
            this.input = input;
            GlobalGameStates.GameState = CeleritySettings.StartingGameState;
            GlobalGameStates.MenuState = CeleritySettings.StartingMenuState;
            GlobalGameStates.CameraState = CeleritySettings.StartingCameraState;
        }
        #endregion /Constructor

        #region Update
        public void Update(GameTime gameTime, int elapsedMs)
        {
            HandleInputs();
            if (GlobalGameStates.GameState == GameState.InGame)
            {
                GlobalGameStates.PlayerAliveMilliseconds += elapsedMs;
            }

            this.ChaosFactor = this.ComputeChaos(timeSinceCrash);
            timeSinceCrash += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0d;
        }

        void HandleInputs()
        {
            if (input.FireSmartbomb)
            {
                OnFireSmartBomb();
                input.FireSmartbomb = false;
            }

            if (input.HasUnprocessedStartGame)
            {
                input.HasUnprocessedStartGame = false;
                OnStartGame();
            }

            if (input.HasUnprocessedFlipMute)
            {
                input.HasUnprocessedFlipMute = false;
                FlipMuteState();
            }

            if (input.HasUnprocessedBack)
            {
                input.HasUnprocessedBack = false;
                GlobalGameStates.GameState = GameState.Menu;
                GlobalGameStates.MenuState = MenuState.MainMenu;
            }
        }
        #endregion /Update

        #region Game Logic Events
        public void OnUIClick()
        {
            audio.PlayClick();
        }

        public void OnCrash()
        {
            if (GlobalGameStates.GameState != GameState.InGame)
            {
                return;
            }

            audio.PlayCrash();
            GlobalGameStates.LivesLeft--;
            ChaosFactor = 0.01f;
            timeSinceCrash = 0.0;
            if (GlobalGameStates.LivesLeft <= 0)
            {
                GlobalGameStates.GameState = GameState.GameOver;
                this.ChaosFactor = 0f;
            }
        }

        public void OnSmartBombHandled()
        {
            DoFireSmartBomb = false;
        }

        void OnFireSmartBomb()
        {
            if (GlobalGameStates.BombsLeft > 0)
            {
                GlobalGameStates.BombsLeft--;
                audio.PlaySmartBomb();
                DoFireSmartBomb = true; //this is up to the World to set back to false when processed
            }
        }

        public void OnSetCameraFpsLow()
        {
            GlobalGameStates.CameraState = CameraState.LowFPS;
            OnUIClick();
        }

        public void OnSetCameraFpsHigh()
        {
            GlobalGameStates.CameraState = CameraState.FullFPS;
            OnUIClick();
        }

        public void OnSetCameraFpsNever()
        {
            GlobalGameStates.CameraState = CameraState.Override;
            OnUIClick();
        }

        public void OnBack()
        {
            GlobalGameStates.GameState = GameState.Menu;
            GlobalGameStates.MenuState = MenuState.MainMenu;
            OnUIClick();
        }

        public void OnStartGame()
        {
            GlobalGameStates.GameState = GameState.InGame;
            GlobalGameStates.MenuState = MenuState.MainMenu;
            GlobalGameStates.BombsLeft = 3;
            GlobalGameStates.LivesLeft = 3;
            GlobalGameStates.PlayerAliveMilliseconds = 0;
            ChaosFactor = 0.01f;
            DoFireSmartBomb = true; //this is up to the World to set back to false when processed
            OnUIClick();
        }
        #endregion /Game Logic Events

        #region Helpers
        void FlipMuteState()
        {
            GlobalGameStates.MuteState = GlobalGameStates.MuteState == MuteState.Muted ? MuteState.NotMuted : MuteState.Muted;
        }

        public float ComputeChaos(double time)
        {
            return (float)(1.0 - (1.0 / Math.Exp(time / 20.0)));
        }
        #endregion /Helpers
    }
}
